package de.playmee;

import de.playmee.handler.AccountHandler;
import de.playmee.handler.ChannelHandler;
import de.playmee.handler.ChannelTrackRatingHandler;
import de.playmee.handler.MusicHandler;
import de.playmee.handler.PlaylistHandler;
import de.playmee.handler.RegionHandler;
import de.playmee.services.MusicService;
import de.playmee.tasks.CheckAccountTask;
import de.playmee.tasks.PrepareHandlerTask;
import de.playmee.tasks.PrepareHandlerTask.AnalyzeMusicListener;
import de.playmee.tasks.PrepareHandlerTask.PrepareHandlerListener;
import de.playmee.tasks.CheckAccountTask.AccountCheckedListener;
import de.playmee.tasks.RegisterAccountTask.RegisterAccountListener;
import de.playmee.views.RegisterDialog;
import de.playmee.dialogs.CustomDialog;
import de.playmee.dialogs.ProgressBarDialog;
import de.playmee.dialogs.ProgressWheelDialog;
import de.playmee.enums.Result;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;

public class LoginActivity extends Activity implements
		AccountCheckedListener, RegisterAccountListener,
		PrepareHandlerListener, AnalyzeMusicListener {

	private final String TAG = "LoadingActivity";
	
	private final int HANDLE_WHEEL_SHOW = 0;
	private final int HANDLE_WHEEL_DISMISS = 1;
	private final int HANDLE_BAR_SHOW = 2;
	private final int HANDLE_BAR_UPDATE = 3;
	private final int HANDLE_BAR_DISMISS = 4;
	private final int HANDLE_REGISTER_SUCCESS = 5;
	private final int HANDLE_REGISTER_ERROR = 6;
	
	private Playmee application;
	
	private EditText userInput;
	private EditText passwordInput;
	private Button loginButton;
	
	private TextView registerButton;
	private Result registerResult;
	
	private AccountHandler aHandler;
	private String username;
	private String password;
	
	private ProgressWheelDialog progressWheelDialog;
	
	private ProgressBarDialog progressBarDialog;
	private int progressBarMax;
	private String progressBarMessage;
	private int progressBarValue;
	
	private Handler commandHandler;
	
	/**
	 * called when the activity is first created
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.login);
		
		application = (Playmee) getApplication();
		
		aHandler = new AccountHandler(getSharedPreferences(AccountHandler.PREFERENCES, MODE_PRIVATE));
		
		progressWheelDialog = new ProgressWheelDialog(this);
		
		userInput = (EditText) findViewById(R.id.loginUserInput);
		passwordInput = (EditText) findViewById(R.id.loginPasswordInput);
		loginButton = (Button) findViewById(R.id.loginButton);
		registerButton = (TextView) findViewById(R.id.registerButton);
		
		// login button
		loginButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (userInput.getText().length() > 0 && passwordInput.getText().length() > 0) {
					progressWheelDialog.show();
					username = userInput.getText().toString().trim();
					password = passwordInput.getText().toString().trim();
					checkAccount();
				}
			}
		});
		
		// try to login if enter is clicked on the keyboard
		passwordInput.setOnEditorActionListener(new OnEditorActionListener() {
			@Override
			public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
				loginButton.performClick();
				return false;
			}
		});
		
		// register a new account
		registerButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				new RegisterDialog(LoginActivity.this, aHandler, LoginActivity.this).show();
			}
		});
		
		// handler to handle various commands
		commandHandler = new Handler() {
			public void  handleMessage(Message msg) {
				int what = msg.what;
						
				// show progress wheel
				if (what == HANDLE_WHEEL_SHOW) {
					progressWheelDialog.show();
				}
						
				// dismiss progress wheel
				else if (what == HANDLE_WHEEL_DISMISS) {
					progressWheelDialog.dismiss();
				}
						
				// show progress bar
				else if (what == HANDLE_BAR_SHOW) {
					progressBarDialog = new ProgressBarDialog(LoginActivity.this);
					progressBarDialog.show(progressBarMax, progressBarMessage);
				}
				
				// update the progress value of the progress bar
				else if (what == HANDLE_BAR_UPDATE) {
					progressBarDialog.update(progressBarValue);
				}
				
				else if (what == HANDLE_BAR_DISMISS) {
					progressBarDialog.dismiss();
				}
						
				// done registering (success)
				else if (what == HANDLE_REGISTER_SUCCESS) {
					username = aHandler.getUsername();
					password = aHandler.getPassword();
					userInput.setText(username);
					passwordInput.setText(password);
					progressWheelDialog.dismiss();
					CustomDialog.showInfoDialog(LoginActivity.this, "Account registered",
							"Your account was successfully registered."
							+ "\nUsername: " + username + "\nPassword: " + password);
					// TODO login automatically
				}
						
				// done registering (error)
				else if (msg.what == HANDLE_REGISTER_ERROR) {
					progressWheelDialog.dismiss();
					CustomDialog.showAlertDialog(LoginActivity.this, "Registration failed",
							"Your account could not be registered. "
							+ registerResult.getMessage());
				}
			}
		};
		
		// TODO forgotten password
		
		init();
	}
	
	@Override
	protected void onRestart() {
		super.onRestart();
		//init();
		
		// stop if playlist is still playing
		startService(new Intent(MusicService.ACTION_STOP));
	}
	
	private void init() {
		// load stored account details
		aHandler.loadUsernameFromPreferences();
		aHandler.loadPasswordFromPreferences();
		
		// fill text views
		userInput.setText(aHandler.getUsername());
		passwordInput.setText(aHandler.getPassword());
	}
	
	/**
	 * check username and password
	 */
	private void checkAccount() {
		Log.i(TAG, "Checking network connectivity...");
		
		// username and password are stored already
		// and they were not modified
		if (aHandler.accountDetailsAvailable() && username.equals(aHandler.getUsername())
				&& password.equals(aHandler.getPassword())) {
			onAccoutChecked(Result.Success);
		}
		
		// application has no connection to the internet
		else if (!((Playmee) getApplication()).hasNetworkConnection()) {
			Log.e(TAG, "Cannot check user account. No network connection available.");
			CustomDialog.showAlertDialog(LoginActivity.this, "Login failed",
					Result.Network_Connection.getMessage());
			progressWheelDialog.dismiss();
		}
		
		// try to login with given username and password
		else {
			Log.i(TAG, "Start checking the user account...");
			(new CheckAccountTask(aHandler, username, password, this)).execute();
		}
	}
	
	@Override
	public void onAccoutChecked(Result result) {
		Log.i(TAG, "Done checking the user account.");
		if (result == Result.Success) {
			// no error, so store username and password
			aHandler.setUsername(username);
			aHandler.setPassword(password);
			application.setAccountHandler(aHandler);
			// go on with preparing all handler
			new PrepareHandlerTask(this, aHandler, application.getWeather(), this, this).execute();
		} else {
			// error, so show an alert dialog with the error message
			CustomDialog.showAlertDialog(LoginActivity.this, "Login failed",
					result.getMessage());
			commandHandler.sendEmptyMessage(HANDLE_WHEEL_DISMISS);
		}
	}
	
	@Override
	public void onStartRegisteringAccount() {
		commandHandler.sendEmptyMessage(HANDLE_WHEEL_SHOW);
	}
	
	@Override
	public void onAccoutRegistered(Result result, String username, String password) {
		registerResult = result;
		if (result == Result.Success) {
			aHandler.setUsername(username);
			aHandler.setPassword(password);
			commandHandler.sendEmptyMessage(HANDLE_REGISTER_SUCCESS);
		} else {
			commandHandler.sendEmptyMessage(HANDLE_REGISTER_SUCCESS);
		}
	}
	
	@Override
	public void onTrackCountAnalyzed(int countOfTracksOnDevice) {
		progressBarMax = countOfTracksOnDevice;
		progressBarMessage = "Analyzing music...";
		commandHandler.sendEmptyMessage(HANDLE_WHEEL_DISMISS);
		commandHandler.sendEmptyMessage(HANDLE_BAR_SHOW);
	}
	
	@Override
	public void onTrackAnalyzed(int countOfAnalyzedTracks) {
		progressBarValue = countOfAnalyzedTracks;
		commandHandler.sendEmptyMessage(HANDLE_BAR_UPDATE);
	}
	
	@Override
	public void onMusicHandlerPrepared(MusicHandler mHandler) {
		application.setMusicHandler(mHandler);
		commandHandler.sendEmptyMessage(HANDLE_BAR_DISMISS);
		commandHandler.sendEmptyMessage(HANDLE_WHEEL_SHOW);
		
		// create ImageManager to manage the album arts
		application.setImageManager(new ImageManager(getApplicationContext(), mHandler,
				Track.DUMMY_ALBUM_ART));
	}
	
	@Override
	public void onChannelTrackRatingHandlerPrepared(ChannelTrackRatingHandler ctrHandler) {
		application.setChannelTrackRatingHandler(ctrHandler);
	}
	
	@Override
	public void onChannelHandlerPrepared(ChannelHandler cHandler) {
		application.setChannelHandler(cHandler);
	}

	@Override
	public void onRegionHandlerPrepared(RegionHandler rHandler) {
		application.setRegionHandler(rHandler);
	}

	@Override
	public void onPlaylistHandlerPrepared(PlaylistHandler pHandler) {
		application.setPlaylistHandler(pHandler);
	}
	
	@Override
	public void onAllHandlerPrepared() {
		commandHandler.sendEmptyMessage(HANDLE_WHEEL_DISMISS);
		startActivity(new Intent(LoginActivity.this, MainActivity.class));
	}
}
